package com.huterox.second.websocket;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.huterox.second.dao.message.MessageSend;
import com.huterox.second.server.MessageService;
import com.huterox.second.server.TalkService;
import com.huterox.second.utils.MessageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@RestController
@ServerEndpoint(value = "/chat",configurator = GetHttpSessionConfigurator.class)
public class ChatEndpoint {

    private static TalkService talkService;
    private static MessageService messageService;
    @Autowired
    public void setTalkService(TalkService talkService){
        ChatEndpoint.talkService = talkService;
    }
    @Autowired
    public void setMessageService(MessageService messageService){
        ChatEndpoint.messageService = messageService;
    }

    //用来存储每个用户客户端对象的ChatEndpoint对象
    private static Map<Long,ChatEndpoint> onlineUsers = new ConcurrentHashMap<>();

    private static Map<Long,String> onlineUserNames = new ConcurrentHashMap<>();
//    用来存储talkID 的这样只需要查询一次数据库就可以拿到talkID了，加快速度
    private static Map<String,Long> talkID = new ConcurrentHashMap<>();
    //声明session对象，通过对象可以发送消息给指定的用户
    private Session session;

    //声明HttpSession对象，我们之前在HttpSession对象中存储了用户id
    private HttpSession httpSession;

    //连接建立
    @OnOpen
    public void onOpen(Session session, EndpointConfig config){
        this.session = session;
        HttpSession httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
        this.httpSession = httpSession;
        //存储登陆的对象
        Long userID = (Long) httpSession.getAttribute("id");
        String name = (String) httpSession.getAttribute("name");
        System.out.println("id:"+userID+"-name:"+name+"进入聊天室");
        onlineUsers.put(userID,this);
        onlineUserNames.put(userID,name);

        //将当前在线用户的用户名推送给所有的客户端
        //1 获取消息

        String message = MessageUtils.getMessage(true, null, null,getUsers());
        //2 调用方法进行系统消息的推送
        broadcastAllUsers(message);
    }

    private void broadcastAllUsers(String message){
        try {
            //将消息推送给所有的客户端
            Set<Long> IDS = onlineUsers.keySet();
            for (Long ID : IDS) {
                ChatEndpoint chatEndpoint = onlineUsers.get(ID);
                chatEndpoint.session.getBasicRemote().sendText(message);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //返回在线用户ID
    private Set<Long> getId(){
        return onlineUsers.keySet();
    }

    //返回在线用户名
//    {"id":4,"username":"小敏"},
    private Set<Map<String,String>> getUsers(){
        Set<Map<String,String>> set = new HashSet<>();
        for (Map.Entry<Long, String> entry : onlineUserNames.entrySet()) {
            Map<String,String> temp = new HashMap<>();
            temp.put("id",String.valueOf(entry.getKey()));
            temp.put("username",entry.getValue());
            set.add(temp);

        }
        return set;
    }

    private Long getTalkID(Long mytalk,Long shetalk){

        String Key = mytalk+"to"+shetalk;
        if (talkID.get(Key)!=null){
            return talkID.get(Key);
        }else {
            Long talkId = talkService.getTalkId(mytalk, shetalk);
            talkID.put(Key,talkId);
            return talkId;
        }

    }

    private Long SaveMessage(Long mytalk,Long shetalk,String message){
        Long talkID = this.getTalkID(mytalk, shetalk);
        return messageService.SaveMessage(message, talkID);
    }

    //收到消息,并且我们需要把消息存储到数据库内
    @OnMessage
    public void onMessage(String message, Session session){
        //将数据转换成对象
        try {
            ObjectMapper mapper =new ObjectMapper();
            System.out.println(message);
            MessageSend mess = mapper.readValue(message, MessageSend.class);
            Long toID = mess.getToID();
            String toName = mess.getToName();
            String data = mess.getMessage();
            Long userID = (Long) httpSession.getAttribute("id");

            String userName = (String) httpSession.getAttribute("name");
//            在这里存储消息
            this.SaveMessage(userID,toID,data);
            System.out.println(mess);
            String resultMessage = MessageUtils.getMessage(false, userID,userName,mess);
            //发送数据
            if(toID!=null) {
//                发送的数据长这个样子
//                {"isSystem": false,
//                        "fromID": 2,
//                        "message":{"toID":1,"toName":"Futerox","message":"Hello"}
//                }
                onlineUsers.get(toID).session.getBasicRemote().sendText(resultMessage);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    //关闭
    @OnClose
    public void onClose(Session session) {
        Long userID = (Long) httpSession.getAttribute("id");
        //从容器中删除指定的用户
        onlineUsers.remove(userID);
        onlineUserNames.remove(userID);
        String message = MessageUtils.getMessage(true,null,null,getUsers());
        broadcastAllUsers(message);
    }}

